package cn.blunce.weather.base;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import cn.blunce.weather.models.AstroWeather;
import cn.blunce.weather.models.AstroWeatherDao;
import cn.blunce.weather.models.CityID;
import cn.blunce.weather.models.CityIDDao;
import cn.blunce.weather.models.DailyForcast;
import cn.blunce.weather.models.DailyForcastDao;
import cn.blunce.weather.models.DaoMaster;
import cn.blunce.weather.models.DaoSession;
import cn.blunce.weather.models.HourlyForcast;
import cn.blunce.weather.models.HourlyForcastDao;
import cn.blunce.weather.models.Suggestion;
import cn.blunce.weather.models.SuggestionDao;
import cn.blunce.weather.models.WeatherAQI;
import cn.blunce.weather.models.WeatherAQIDao;
import cn.blunce.weather.models.WeatherDaily;
import cn.blunce.weather.models.WeatherDailyDao;
import cn.blunce.weather.models.WeatherID;
import cn.blunce.weather.models.WeatherIDDao;
import cn.blunce.weather.models.WeatherMessage;
import cn.blunce.weather.models.WeatherMessageDao;
import cn.blunce.weather.models.WeatherNow;
import cn.blunce.weather.models.WeatherNowCond;
import cn.blunce.weather.models.WeatherNowCondDao;
import cn.blunce.weather.models.WeatherNowDao;
import cn.blunce.weather.models.WeatherSuggestion;
import cn.blunce.weather.models.WeatherSuggestionDao;
import cn.blunce.weather.models.WeatherTmp;
import cn.blunce.weather.models.WeatherTmpDao;
import cn.blunce.weather.models.WeatherWind;
import cn.blunce.weather.models.WeatherWindDao;

/**
 * Created by Experiment on 2016/4/25 0025.
 */
public class AppDB {

    private static DaoMaster.DevOpenHelper sHelper;
    private static SQLiteDatabase sDataBase;
    private static DaoMaster sDaoMaster;
    private static DaoSession sDaoSession;

    private static AstroWeatherDao sAstroWeatehrDao;
    private static CityIDDao sCityIDDao;
    private static DailyForcastDao sDailyForcastDao;
    private static HourlyForcastDao sHourlyForcastDao;
    private static SuggestionDao sSuggestionDao;
    private static WeatherAQIDao sWeatherAQIDao;
    private static WeatherDailyDao sWeatherDailyDao;
    private static WeatherIDDao sWeatherIDDao;
    private static WeatherMessageDao sWeatherMessageDao;
    private static WeatherNowDao sWeatherNowDao;
    private static WeatherNowCondDao sWeatherNowCondDao;
    private static WeatherSuggestionDao sWeatherSuggsetionDao;
    private static WeatherTmpDao sWeatherTmpDao;
    private static WeatherWindDao sWeatherWindDao;

    private static Context sContext;

    private static AppDB sAppDB = null;

    private AppDB(Context context) {
        sContext = context;
        sHelper = new DaoMaster.DevOpenHelper(sContext, "weather_db", null);
        sDataBase = sHelper.getWritableDatabase();
        sDaoMaster = new DaoMaster(sDataBase);
        sDaoSession = sDaoMaster.newSession();

        sAstroWeatehrDao = sDaoSession.getAstroWeatherDao();
        sCityIDDao = sDaoSession.getCityIDDao();
        sDailyForcastDao = sDaoSession.getDailyForcastDao();
        sHourlyForcastDao = sDaoSession.getHourlyForcastDao();
        sSuggestionDao = sDaoSession.getSuggestionDao();
        sWeatherAQIDao = sDaoSession.getWeatherAQIDao();
        sWeatherDailyDao = sDaoSession.getWeatherDailyDao();
        sWeatherIDDao = sDaoSession.getWeatherIDDao();
        sWeatherMessageDao = sDaoSession.getWeatherMessageDao();
        sWeatherNowDao = sDaoSession.getWeatherNowDao();
        sWeatherNowCondDao = sDaoSession.getWeatherNowCondDao();
        sWeatherSuggsetionDao = sDaoSession.getWeatherSuggestionDao();
        sWeatherTmpDao = sDaoSession.getWeatherTmpDao();
        sWeatherWindDao = sDaoSession.getWeatherWindDao();
    }

    public static synchronized AppDB getInstance(Context context) {
        if (sAppDB == null)
            sAppDB = new AppDB(context);
        return sAppDB;
    }

    public boolean add(Object object) {
        boolean tag = true;
        if (new AstroWeather().getClass().getName().equals(object.getClass().getName()))
            sAstroWeatehrDao.insert((AstroWeather) object);
        else if (new CityID().getClass().getName().equals(object.getClass().getName()))
            sCityIDDao.insert((CityID) object);
        else if (new DailyForcast().getClass().getName().equals(object.getClass().getName()))
            sDailyForcastDao.insert((DailyForcast) object);
        else if (new HourlyForcast().getClass().getName().equals(object.getClass().getName()))
            sHourlyForcastDao.insert((HourlyForcast) object);
        else if (new Suggestion().getClass().getName().equals(object.getClass().getName()))
            sSuggestionDao.insert((Suggestion) object);
        else if (new WeatherAQI().getClass().getName().equals(object.getClass().getName()))
            sWeatherAQIDao.insert((WeatherAQI) object);
        else if (new WeatherDaily().getClass().getName().equals(object.getClass().getName()))
            sWeatherDailyDao.insert((WeatherDaily) object);
        else if (new WeatherID().getClass().getName().equals(object.getClass().getName()))
            sWeatherIDDao.insert((WeatherID) object);
        else if (new WeatherMessage().getClass().getName().equals(object.getClass().getName())) {
            WeatherMessage message = (WeatherMessage) object;
            List<WeatherMessage> messages = sWeatherMessageDao.queryBuilder().where(WeatherMessageDao
                    .Properties.City_id.eq((message).getCity_id()), WeatherMessageDao
                    .Properties.Update.eq(message.getUpdate())).list();
            if (messages.size() == 0)
                sWeatherMessageDao.insert(message);
            else {
                message.setId(messages.get(0).getId());
                sWeatherMessageDao.insertOrReplace(message);
            }
        } else if (new WeatherNow().getClass().getName().equals(object.getClass().getName()))
            sWeatherNowDao.insert((WeatherNow) object);
        else if (new WeatherNowCond().getClass().getName().equals(object.getClass().getName()))
            sWeatherNowCondDao.insert((WeatherNowCond) object);
        else if (new WeatherSuggestion().getClass().getName().equals(object.getClass().getName()))
            sWeatherSuggsetionDao.insert((WeatherSuggestion) object);
        else if (new WeatherTmp().getClass().getName().equals(object.getClass().getName()))
            sWeatherTmpDao.insert((WeatherTmp) object);
        else if (new WeatherWind().getClass().getName().equals(object.getClass().getName()))
            sWeatherWindDao.insert((WeatherWind) object);
        else
            tag = false;
        return tag;
    }

    public List<WeatherID> getAllWeatherIDs() {
        return sWeatherIDDao.loadAll();
    }

    public List<CityID> getAllCityIDs() {
        return sCityIDDao.loadAll();
    }

    public List<CityID> queryCityByCityID(String cityID) {
        return sCityIDDao.queryBuilder().where(CityIDDao.Properties.Id.eq(cityID)).list();
    }

    public List<CityID> queryCitiesByNames(String names) {
        List<CityID> cityIDs = sCityIDDao.loadAll();
        List<CityID> cities = new ArrayList<>();
        for (CityID city : cityIDs)
            if (city.getCity().contains(names))
                cities.add(city);
        return cities;
    }

    public List<CityID> queryCityByCityName(String cityName) {
        return sCityIDDao.queryBuilder().where(CityIDDao.Properties.City.eq(cityName)).list();
    }

    public List<WeatherID> queryWeatherIDByCode(String code) {
        return sWeatherIDDao.queryBuilder().where(WeatherIDDao.Properties.Code.eq(code)).list();
    }

    public List<WeatherMessage> queryWeatherMessageByCity(String city_id) {
        List<WeatherMessage> messages = sWeatherMessageDao.queryBuilder().where(WeatherMessageDao.Properties.City_id.eq(city_id)).list();
        Collections.sort(messages, new Comparator<WeatherMessage>() {
            @Override
            public int compare(WeatherMessage lhs, WeatherMessage rhs) {
                return -(lhs.getUpdate().compareTo(rhs.getUpdate()));
            }
        });
        return messages;
    }

    public void DBClear() {
        sDaoSession.clear();
    }
}
